<?php
new pionwipe();


/**
 *
 * @author pion
 * @abstract Deletes oldest dir on device inside paths found in vfs file.
 * @link http://code.google.com/u/pion.boxes/
 * @version 1.0
 *
 */
class pionwipe
{
	# Config
	public $vfs_file = 'C:\PROGRAMME\ioFTPD\etc\default.vfs';
	public $min_space_left_on_disk = 3; // times multiplier
	public $skiplist = array(
	# Regex patterns to skip
		'programme',
		'Program Files',
		'(?:\\\\|\\/)PRE(?:\\\\|\\/)?', // Block predirs from autowipe (Both \ and / allowed before and after 'PRE')
		':$', // c: , d: etc.
		'ioFTPD' // dirs inside ioFTPD
	);

	private $multiplier = 1073741824; //GB


	function __construct($vfs_file = '',$skiplist = '')
	{
		# Parse input
		$this->vfs_file = (empty($vfs_file)) ? $this->vfs_file : $vfs_file;
		$this->skiplist = (empty($skiplist)) ? $this->skiplist : $skiplist;


		if (false == ($vfs_dirs = $this->get_vfs_dirs($this->vfs_file,$this->skiplist)))
		{
			die('Failed to read vfs file '.$this->vfs_file);
		}

		# Locate disks with little space
		if (false == ($devices_with_little_space = $this->check_free_space($vfs_dirs))) die('Disk space within parameters');

		# List all dirs on devices with little space sorted by date (oldest on top)
		$dirlist = $this->get_date_sorted_dirs($vfs_dirs,$devices_with_little_space);

		# Delete oldest dir (including content) until there's enough free space
		set_time_limit(10); //Avoid endless loop to burn all cpu too long
		while ((false !== ($this->check_free_space($vfs_dirs))) && (!empty($dirlist)))
		{
			$oldest_dir = array_shift($dirlist);
			$this->deltree($oldest_dir);
		}
		echo "Successfully freed enough space";
	}

	function deltree($dir)
	{
		{
			if(substr($directory,-1) == '/')
			{
				$directory = substr($directory,0,-1);
			}
			if(!file_exists($directory) || !is_dir($directory))
			{
				return false;
			}elseif(is_readable($directory))
			{
				$handle = opendir($directory);
				while (false !== ($item = readdir($handle)))
				{
					if($item != '.' && $item != '..')
					{
						$path = $directory.'/'.$item;
						if(is_dir($path))
						{
							$this->deltree($path);
						}else{
							unlink($path);
						}
					}
				}
				closedir($handle);

				if(!rmdir($directory))
				{
					return false;
				}

			}
			return true;
		}
	}

	function check_free_space($vfs_dirs)
	{
		$devices_with_little_space = array();
		foreach ($vfs_dirs as $dir)
		{
			if (!is_dir($dir)) continue;
			if (disk_free_space($dir) < $this->min_space_left_on_disk*$this->multiplier)
			{
				if (preg_match('/^((?:[a-z]|[A-Z]):)/',$dir,$match)) $devices_with_little_space[] = $match[1];
			}
		}
		$devices_with_little_space = array_unique($devices_with_little_space);
		return (empty($devices_with_little_space)) ? false : $devices_with_little_space;
	}

	function get_vfs_dirs($vfs,$skiplist = '')
	{
		if (empty($vfs)) return false;
		if (is_file($vfs))
		{
			$vfs_content = file_get_contents($vfs);
		}
		else
		{
			// Test data
			$vfs_content = '
"c:\program files\ioFTPD\etc\VFS" 		/
"E:\sample" 							/sample
"G:\FTP\DIR1" 							/DIR1
"G:\FTP\DIR2" 							/DIR2
"c:\program files\ioFTPD\etc\VFSADMIN" 	/STAFF
"c:" 									/STAFF/C-drive
"d:" 									/STAFF/D-drive

';
		}
		preg_match_all('/"(.+?)"/',$vfs_content,$matches);

		$dirs = array();
		foreach ($matches[1] as $path) //Each vfs path
		{
			foreach ($skiplist as $regex)
			{
				if (preg_match('/'.$regex.'/',$path)) continue 2;
			}
			$dirs[] = $path;
		}
		return $dirs;
	}

	function get_date_sorted_dirs($paths,$devices)
	{
		if (empty($paths)) return false;
		if (empty($devices)) return false;

		$dirs = array();
		foreach ($paths as $path)
		{
			if (!is_dir($path)) continue;
			preg_match('/^((?:[a-z]|[A-Z]):)/',$path,$match);
			if (!in_array($match[1],$devices)) continue; // Skip folders on devices with enough space

			$dh = opendir($path);
			$list = array();
			while($subdir = readdir($dh)){
				if (!is_dir($path.'/'.$subdir)) continue;
				if ($subdir != '.' and $subdir != '..'){
					// add the dirname, to be sure not to
					// overwrite a array key
					$ctime = filectime($path .'/'. $subdir) . ',' . $subdir;
					$dirs[$ctime] = $path.'/'.$subdir; //Full path
				}
			}
			closedir($dh);
		}
		ksort($dirs); //Sort by date - oldest on top (sort by index)

		return $dirs;
	}

}

?>